{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 字典的使用"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 创建字典\n",
    "\n",
    "- 语法：\n",
    "    - 使用 `{}`\n",
    "        - `{k1:v1,k2:v2,k3:v3...}`\n",
    "    - 使用 `dict()`\n",
    "        - `dict(k1 = v1, k2 = v2, k3 = v3)`\n",
    "            - 每一个参数都是一个键值对\n",
    "            - 参数名就是键\n",
    "            - 参数值就是值\n",
    "            - 这种方式创建的字典，`key` 都是字符串\n",
    "        - `dict(包含有双值子序列的序列)`\n",
    "            - 也可以将一个包含有双值子序列的序列转换为字典\n",
    "            - 双值序列指序列中只有两个值（如 `[1,2]`、`('a',3)`、`'ab'`）\n",
    "            - 子序列指序列中的元素也是序列"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "d = dict(name = 'Issac', age = 18, gender = '🟦')\n",
    "print(f'd = {d}, type(d) = {type(d)}')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "d = dict([('name','Issac'),'Na',['age',18]])\n",
    "print(f'd = {d}, type(d) = {type(d)}')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## `len()`\n",
    "\n",
    "- 获取字典中键值对的个数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "d = dict(name = 'Issac', age = 18, gender = '🟦')\n",
    "print(f'd = {d}, len(d) = {len(d)}')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## `in` 和 `not in`\n",
    "\n",
    "### `in`\n",
    "\n",
    "- 检查字典中是否包含指定的键\n",
    "\n",
    "### `not in`\n",
    "\n",
    "- 检查字典中是否不包含指定的键"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "d = dict(name = 'Issac', age = 18, gender = '🟦')\n",
    "\n",
    "print(f\"d = {d}, 'name' in d = {'name' in d}\")\n",
    "print(f\"d = {d}, 'name' not in d = {'name' not in d}\")\n",
    "print(f\"d = {d}, 'class' in d = {'class' in d}\")\n",
    "print(f\"d = {d}, 'class' not in d = {'class' not in d}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 获取字典中的值\n",
    "\n",
    "- 根据键来获取值\n",
    "- 语法：\n",
    "    - `d[key]`\n",
    "        - 通过 `[]` 来获取值时，如果键不存在，会抛出异常 `KeyError`\n",
    "    - `d.get(key,[default])`\n",
    "        - 通过 `.get()` 来获取值时，如果键不存在，会返回 `None`\n",
    "        - 也可以指定一个默认值 `default`，来作为第二个参数，这样获取不到值时会返回默认值"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "d = dict(name = 'Issac', age = 18, gender = '🟦')\n",
    "\n",
    "print(f\"d = {d}, d['name'] = {d['name']}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "d = dict(name = 'Issac', age = 18, gender = '🟦')\n",
    "\n",
    "print(f\"d = {d}, d.get('name') = {d.get('name')}\")\n",
    "print(f\"d = {d}, d.get('class') = {d.get('class')}\")\n",
    "print(f\"d = {d}, d.get('class',1) = {d.get('class',1)}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 修改字典\n",
    "\n",
    "- 语法：`d[key] = value`\n",
    "- 如果 `key` 存在则覆盖，不存在则添加"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "d = dict(name = 'Issac', age = 18, gender = '🟦')\n",
    "print(f\"d = {d}, d.get('age') = {d.get('age')}\")\n",
    "\n",
    "d['age'] = 19\n",
    "print(f\"d = {d}, d.get('age') = {d.get('age')}\")\n",
    "\n",
    "d['class'] = 1\n",
    "print(f\"d = {d}, d.get('class') = {d.get('class')}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### `.setdefault()`\n",
    "\n",
    "- 语法：`.setdefault(key,[default])`\n",
    "- 如果 `key` 已经存在于字典中，则返回 `key` 的值，不会对字典做任何操作\n",
    "- 如果 `key` 不存在，则向字典中添加这个 `key`，并设置值为 `default`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "d = dict(name = 'Issac', age = 18, gender = '🟦')\n",
    "\n",
    "d.setdefault('name','Acker')\n",
    "print(f\"d = {d}, d.get('name') = {d.get('name')}\")\n",
    "\n",
    "d.setdefault('class',1)\n",
    "print(f\"d = {d}, d.get('class') = {d.get('class')}\")\n",
    "\n",
    "d.setdefault('health')\n",
    "print(f\"d = {d}, d['health'] = {d['health']}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### `.update()`\n",
    "\n",
    "- 将其它字典中的 `key - value` 添加到当前字典中\n",
    "- 如果有重复的 `key`，则后边的会替换掉当前的"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "d_1 = {'a':1,'b':2,'c':3}\n",
    "d_2 = {'d':4,'e':5,'f':6,'a':7}\n",
    "\n",
    "print(f'd_1 = {d_1}, id(d_1) = {id(d_1)}')\n",
    "\n",
    "d_1.update(d_2)\n",
    "\n",
    "print(f'd_1 = {d_1}, id(d_1) = {id(d_1)}')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 删除字典中的 `key - value`\n",
    "\n",
    "### `del`\n",
    "\n",
    "- 当使用 `del` 删除不存在的 `key` 时，会抛出异常 `KeyError`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "d = dict(name = 'Issac', age = 18, gender = '🟦')\n",
    "print(f'd = {d}')\n",
    "\n",
    "del d['name']\n",
    "print(f'd = {d}')\n",
    "\n",
    "del d['gender']\n",
    "print(f'd = {d}')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### `.popitem()`\n",
    "\n",
    "- 随机删除字典中的一个键值对，一般都会删除最后一个键值对\n",
    "- 删除之后，它会将删除的 `key - value` 作为一个 `tuple` 类型的返回值返回\n",
    "- 当使用 `.popitem()` 删除一个空字典时，会抛出异常 `KeyError`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "d = dict(name = 'Issac', age = 18, gender = '🟦')\n",
    "print(f'd = {d}')\n",
    "\n",
    "rst = d.popitem()\n",
    "print(f'd = {d}')\n",
    "print(f'rst = {rst}, type(rst) = {type(rst)}')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### `.pop(key[,default])`\n",
    "\n",
    "- 根据 `key` 删除字典中的 `key - value`\n",
    "- 会将被删除的 `value` 返回\n",
    "- 如果删除不存在的 `key` 会抛出异常 `KeyError`\n",
    "- 如果指定了默认值 `default`，删除不存在的 `key` 时，则不会报错，而是直接返回默认值"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "d = dict(a=1,b=2,c=3,d=4)\n",
    "print(f'd = {d}')\n",
    "\n",
    "rst_1 = d.pop('c')\n",
    "print(f'd = {d}')\n",
    "print(f'rst_1 = {rst_1}')\n",
    "\n",
    "rst_2 = d.pop('z','默认值')\n",
    "print(f'd = {d}')\n",
    "print(f'rst_2 = {rst_2}')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### `.clear()`\n",
    "\n",
    "- 清空字典"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "d = dict(a=1,b=2,c=3,d=4)\n",
    "print(f'd = {d}')\n",
    "\n",
    "rst_1 = d.clear()\n",
    "print(f'd = {d}')\n",
    "print(f'rst = {rst}')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## `.copy()`\n",
    "\n",
    "- 该方法用于对字典进行**浅复制**\n",
    "- 复制以后的对象和原对象是独立的，修改一个**不会**影响另一个"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "d_1 = {'a':1,'b':2,'c':3,'d':4}\n",
    "d_2 = d_1\n",
    "print(f'd_1 = {d_1}, id(d_1) = {id(d_1)}')\n",
    "print(f'd_2 = {d_2}, id(d_2) = {id(d_2)}')\n",
    "\n",
    "d_3 = d_1.copy()\n",
    "print(f'd_1 = {d_1}, id(d_1) = {id(d_1)}')\n",
    "print(f'd_3 = {d_3}, id(d_3) = {id(d_3)}')\n",
    "\n",
    "d_1.setdefault('e',5)\n",
    "print(f'd_1 = {d_1}, id(d_1) = {id(d_1)}')\n",
    "print(f'd_3 = {d_3}, id(d_3) = {id(d_3)}')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 浅复制\n",
    "\n",
    "- 浅复制只会简单的复制对象内部的值，如果值也是一个可变对象，这个可变对象不会被复制"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "jst1 = {'Issac':{'name':'Hongli Ji','gender':'boy','hobby':'play'},'Acker':{'name':'Chen Yu','gender':'girl','hobby':'study'}}\n",
    "jst2 = jst1.copy()\n",
    "\n",
    "print(f'jst1 = {jst1}, id(jst1) = {id(jst1)}')\n",
    "print(f'jst2 = {jst2}, id(jst2) = {id(jst2)}')\n",
    "\n",
    "# jst1['Issac']['hobby'] = 'cook'\n",
    "jst1.get('Issac').update({'hobby':'cook'})\n",
    "\n",
    "print(f'jst1 = {jst1}, id(jst1) = {id(jst1)}')\n",
    "print(f'jst2 = {jst2}, id(jst2) = {id(jst2)}')"
   ]
  }
 ],
 "metadata": {
  "interpreter": {
   "hash": "767d51c1340bd893661ea55ea3124f6de3c7a262a8b4abca0554b478b1e2ff90"
  },
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
